package org.convallaria.infrastruct.ce.example;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.convallaria.infrastruct.ce.annotation.CacheEvictAll;
import org.convallaria.infrastruct.ce.annotation.CacheRefresh;
import org.convallaria.infrastruct.ce.annotation.CacheWarmup;
import org.convallaria.infrastruct.ce.util.CacheUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

/**
 * 缓存使用示例服务
 * 演示企业级缓存功能的使用方法
 * 
 * @author gjh
 * @since 2024-09-24
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CacheExampleService {

    private final CacheUtils cacheUtils;

    /**
     * 基本缓存使用示例
     */
    @Cacheable(value = "user-cache", key = "#id")
    public User getUserById(Long id) {
        log.info("从数据库获取用户信息: {}", id);
        // 模拟数据库查询
        return User.builder()
                .id(id)
                .name("用户" + id)
                .email("user" + id + "@example.com")
                .build();
    }

    /**
     * 条件缓存示例
     */
    @Cacheable(value = "user-cache", key = "#id", condition = "#id > 0")
    public User getUserByIdWithCondition(Long id) {
        log.info("从数据库获取用户信息（条件缓存）: {}", id);
        return User.builder()
                .id(id)
                .name("用户" + id)
                .email("user" + id + "@example.com")
                .build();
    }

    /**
     * 缓存更新示例
     */
    @CacheEvict(value = "user-cache", key = "#user.id")
    public void updateUser(User user) {
        log.info("更新用户信息: {}", user.getId());
        // 模拟数据库更新
    }

    /**
     * 批量清除缓存示例
     */
    @CacheEvictAll(value = {"user-cache", "config-cache"})
    public void clearAllUserCache() {
        log.info("清除所有用户相关缓存");
    }

    /**
     * 缓存刷新示例
     */
    @CacheRefresh(value = "user-cache", async = true)
    public void refreshUserCache() {
        log.info("刷新用户缓存");
    }

    /**
     * 缓存预热示例
     */
    @CacheWarmup(value = "user-cache", async = true, order = 1)
    public void warmupUserCache() {
        log.info("预热用户缓存");
        // 预热常用数据
        for (long i = 1; i <= 10; i++) {
            getUserById(i);
        }
    }

    /**
     * 使用CacheUtils的示例
     */
    public User getUserWithUtils(Long id) {
        String key = cacheUtils.generateKey("getUserById", id);
        
        return cacheUtils.getOrCompute("user-cache", key, User.class, () -> {
            log.info("从数据库获取用户信息（使用CacheUtils）: {}", id);
            return User.builder()
                    .id(id)
                    .name("用户" + id)
                    .email("user" + id + "@example.com")
                    .build();
        });
    }

    /**
     * 异步缓存操作示例
     */
    public CompletableFuture<User> getUserAsync(Long id) {
        return CompletableFuture.supplyAsync(() -> {
            log.info("异步获取用户信息: {}", id);
            return getUserById(id);
        });
    }

    /**
     * 用户实体
     */
    @lombok.Data
    @lombok.Builder
    @lombok.NoArgsConstructor
    @lombok.AllArgsConstructor
    public static class User {
        private Long id;
        private String name;
        private String email;
        private String phone;
        private java.time.LocalDateTime createTime;
        private java.time.LocalDateTime updateTime;
        
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            User user = (User) o;
            return java.util.Objects.equals(id, user.id);
        }
        
        @Override
        public int hashCode() {
            return java.util.Objects.hash(id);
        }
    }
}
